"""
python 2d_genetic_deap.py
"""

import random
from deap import base, creator, tools

# 定义问题维度和搜索空间边界
DIMENSION = 2
LOWER_BOUND = -10
UPPER_BOUND = 10

# 创建适应度类型和个体类型
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)

# 创建工具盒
toolbox = base.Toolbox()

# 注册生成个体基因的函数（随机生成 x 和 y 坐标）
toolbox.register("attr_float", random.uniform, LOWER_BOUND, UPPER_BOUND)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=DIMENSION)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

# 定义评估函数
def evaluate_individual(individual):
    x, y = individual
    return evaluate_food_function(x, y),

def evaluate_food_function(x, y):
    # 这里假设一个简单的食物数量函数，实际问题中需替换
    return -(x**2 + y**2)

toolbox.register("evaluate", evaluate_individual)

# 注册遗传操作
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.2)
toolbox.register("select", tools.selTournament, tournsize=3)

# 创建初始种群
# pop = toolbox.population(n=50)
pop = toolbox.population(n=50)


# 运行遗传算法
NGEN = 100
for gen in range(NGEN):
    offspring = toolbox.select(pop, len(pop))
    offspring = list(map(toolbox.clone, offspring))
    for child1, child2 in zip(offspring[::2], offspring[1::2]):
        if random.random() < 0.5:
            toolbox.mate(child1, child2)
            del child1.fitness.values
            del child2.fitness.values
    for mutant in offspring:
        if random.random() < 0.2:
            toolbox.mutate(mutant)
            del mutant.fitness.values
    invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
    fitnesses = map(toolbox.evaluate, invalid_ind)
    for ind, fit in zip(invalid_ind, fitnesses):
        ind.fitness.values = fit
    pop[:] = offspring

# 输出结果
best_ind = tools.selBest(pop, 1)[0]
print("Best position (x, y):", best_ind)
print("Maximum food quantity:", evaluate_food_function(*best_ind))